package com.exampleyyy.demoyyy.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.exampleyyy.demoyyy.ShiTi.AddressBook;
import com.exampleyyy.demoyyy.common.BaseContext;
import com.exampleyyy.demoyyy.common.R;
import com.exampleyyy.demoyyy.service.AddressBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;

@Slf4j
@RestController
@RequestMapping("/addressBook")
public class AddressBookController {
    @Autowired
    private AddressBookService addressBookService;

    /**
     * 新增地址方法
     *
     * 此方法用于接收客户端发送的新地址信息，并将其保存到数据库中
     * 它自动将地址的默认状态标记为非默认（0），并与当前用户关联
     *
     * @param address 地址信息，从请求体中获取
     * @return R<Object> 返回一个结果对象，包含操作状态和消息
     */
    @PostMapping("")
    public R<Object> save(@RequestBody AddressBook address){
        // 设置地址的默认状态为非默认
        address.setIsDefault(0);
        // 将当前用户的ID设置为地址的所有者
        address.setUserId(BaseContext.getCurrentId());
        // 日志输出地址信息，用于调试
        log.info("数据是" + address);
        try {
            // 调用服务层方法保存地址信息到数据库
            addressBookService.save(address);
            // 返回成功结果，代码1表示成功
            return R.success(1, "新增成功", null);
        } catch (Exception e) {
            // 异常处理，输出异常信息，用于调试
            System.out.println("错误是 = " + e);
            // 返回失败结果，代码0表示失败
            return R.error(0, "新增失败", null);
        }
    }

    /**
     * 查询当前登录用户的所有地址信息
     * 此方法通过接收一个地址簿对象作为参数，实际用途是为了获取当前用户的ID，
     * 然后根据这个用户ID查询该用户的所有地址信息
     *
     * @param address 地址簿对象，用于获取当前用户的ID
     * @return 返回一个封装了查询结果的R对象，包含状态码，消息和查询到的地址列表
     */
    @GetMapping("/list")
    public R<Object> DiZhiChaXun (AddressBook address){
        // 设置用户的ID，确保只查询当前登录用户的信息
        address.setUserId(BaseContext.getCurrentId());
        // 记录日志，输出地址信息
        log.info("address = " + address);
        // 创建查询对象
        LambdaQueryWrapper<AddressBook> queryWrapper = new LambdaQueryWrapper<>();
        // 将前端传递来的请求参数赋值给查询对象，如果用户ID不为空，则添加查询条件
        queryWrapper.eq(address.getUserId() != null, AddressBook::getUserId, address.getUserId());
        // 对查询结果按照更新时间降序排序
        queryWrapper.orderByDesc(AddressBook::getUpdateTime);
        // 执行查询并返回结果，封装成R对象表示查询成功
        return  R.success(1,"查询成功", addressBookService.list(queryWrapper));
    }

    /**
     * 查询默认地址
     * 该方法通过发送GET请求查询当前用户默认地址
     * 主要用于获取用户默认的收货地址信息
     */
    @GetMapping("/default")
    public R<Object> moRenDiZhiChaXun(){
        // 初始化查询条件，用于查询特定的地址记录
        LambdaQueryWrapper<AddressBook> queryWrapper = new LambdaQueryWrapper<>();
        // 设置查询条件，根据用户ID查询地址信息
        queryWrapper.eq(AddressBook::getUserId, BaseContext.getCurrentId());
        // 设置查询条件，查找默认地址（通常是设置为1表示默认地址）
        queryWrapper.eq(AddressBook::getIsDefault, 1);
        // 使用服务类的getOne方法根据查询条件获取地址信息
        AddressBook addressBook = addressBookService.getOne(queryWrapper);
        // 检查获取的地址信息是否为空
        if (addressBook == null){
            // 如果为空，返回错误信息，提示没有默认地址
            return R.error(0,"没有默认地址",null);
        }else {
            // 如果不为空，返回成功信息，表示查询成功，并携带地址信息
            return R.success(1,"查询成功",addressBook);
        }
    }


    /**
     * 设置默认地址
     *
     * @param address 更新后的地址信息
     * @return 返回操作结果，包含操作状态和提示信息
     */
    @PutMapping("/default")
    public R<Object> moRenDiZhiSheZhi(@RequestBody AddressBook address){
        // 记录日志，输出地址信息
        log.info("address = " + address);
        // 构建更新条件查询包装器
        LambdaUpdateWrapper<AddressBook> queryWrapper = new LambdaUpdateWrapper<>();
        // 设置更新条件：用户ID等于当前用户ID
        queryWrapper.eq(AddressBook::getUserId, BaseContext.getCurrentId());
        // 将除当前地址外的所有地址设置为非默认地址
        queryWrapper.set(AddressBook::getIsDefault, 0);
        // 执行更新操作
        addressBookService.update(queryWrapper);
        // 将当前地址设置为默认地址
        address.setIsDefault(1);
        // 更新数据库中的地址信息
        addressBookService.updateById(address);
        // 返回操作结果：设置默认地址成功
        return R.success(1, "设置默认地址成功", null);
    }

    /**
     * 根据id查询地址
     *
     * @param id 地址的唯一标识符
     * @return 返回查询结果或错误信息
     */
    @GetMapping("/{id}")
    public R<Object> DiZhiChaXunId(@PathVariable Long id){
        // 根据id获取地址信息
        AddressBook addressBook = addressBookService.getById(id);
        log.info("根据id查询到地址 = " + addressBook);
        // 判断地址信息是否为空
        if (addressBook != null) {
            // 查询成功，返回地址信息
            return R.success(1, "查询地址成功", addressBook);
        } else {
            // 地址不存在，返回错误信息
            return R.error(0, "地址不存在", null);
        }
    }

    /**
     * 根据id修改地址
     *
     * 此方法接收一个AddressBook对象作为请求体，该对象包含了需要修改的地址信息以及对应的id。
     * 方法的目的是在地址簿中找到与给定id对应的地址信息，并对其进行更新。
     *
     * @param addressBook 包含了地址信息和id的AddressBook对象
     * @return 返回一个R<Object>对象，包含修改地址的结果信息
     */
    @PutMapping("")
    public R<Object> DiZhiXiuGaiId(@RequestBody AddressBook addressBook){
        // 记录修改前的地址信息，用于日志目的
        log.info("修改地址前 = " + addressBook);
        // 调用service层的updateById方法，根据id更新地址信息
        addressBookService.updateById(addressBook);
        // 更新地址的修改时间
        addressBook.setUpdateTime(LocalDateTime.now());
        // 更新地址的修改用户id，这里使用了BaseContext中的当前用户id
        addressBook.setUpdateUser(BaseContext.getCurrentId());
        // 再次记录地址信息，目的是记录更新后的状态
        log.info("修改地址 = " + addressBook);
        // 再次调用service层的updateById方法，确保所有更新的信息都被保存
        addressBookService.updateById(addressBook);
        // 返回一个成功的响应结果，包含成功修改地址的消息
        return R.success(1, "修改地址成功", null);
    }

    /**
     * 根据id删除地址
     *
     * @param id 需要删除的地址的id，通过路径变量传入
     * @return 返回操作结果的封装对象，包括操作状态码、消息和空的数据
     */
    @DeleteMapping("/{id}")
    public R<Object> DiZhiShanChuId(@PathVariable Long id){
        log.info("删除地址id = " + id);
        addressBookService.removeById(id);
        return R.success(1, "删除地址成功", null);
        /*// 调用服务层的方法，尝试根据id删除地址
        boolean result = addressBookService.removeById(id);
        // 根据删除操作的结果，返回不同的响应
        if (result) {
            // 删除成功，返回成功响应
            return R.success(1, "删除地址成功", null);
        } else {
            // 删除失败，返回错误响应
            return R.error(0, "删除地址失败", null);
        }*/
    }
}
